home *** CD-ROM | disk | FTP | other *** search
- /* ARP commands
- * Copyright 1991 Phil Karn, KA9Q
- *
- * Mods by G1EMM
- *
- * Mods by SM6RPZ
- * 1992-05-28 - Added interface to "arp add ..."-command.
- * 1992-07-26 - Small cosmetic changes here and there.
- */
- #include "global.h"
- #include "ctype.h"
- #include "commands.h"
- #include "mbuf.h"
- #include "timer.h"
- #include "internet.h"
- #include "ip.h"
- #include "arp.h"
- #include "rspf.h"
- #include "domain.h"
- #include "session.h"
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: arpcmd.c,v 1.17 1997/08/19 01:19:22 root Exp root $";
- #endif
-
- static int Arp_Sort = 1; /* set Initial sort mode */
- int Maxarpq = 5;
- char ArpDupcall[AXALEN];
- int ArpExpire = ARPLIFE;
-
-
- static int doarpsort (int argc, char *argv[], void *p);
- static void make_arp_string (struct arp_tab * ap, char *buf);
- static int doarpadd (int argc, char *argv[], void *p);
- static int doarpdrop (int argc, char *argv[], void *p);
- static int doarpflush (int argc, char *argv[], void *p);
- static int doarppoll (int argc, char *argv[], void *p);
- static int doarpeaves (int argc, char *argv[], void *p);
- static int doarpexpire (int argc, char *argv[], void *p);
- static int doarpqueue (int argc, char *argv[], void *p);
- static int doarpdupcall (int argc, char *argv[], void *p);
- static void dumparp (void);
-
-
- #ifdef CATALOG
- #include "catalog.h"
-
- #define CAT arpcmd_catalog
-
- #define addusage __STR(0)
- #define noiface __STR(1)
- #define exptime __STR(2)
- #define dropusage __STR(3)
- #define dumpstr __STR(4)
- #define dumpheader __STR(5)
-
- #else /* CATALOG */
- static const char addusage[] = "Usage: arp %s <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>\n";
- static const char noiface[] = "No such interface %s\n";
- static const char exptime[] = "Expire time for arp entries (in sec.)";
- static const char dropusage[] = "Usage: arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>\n";
- static const char dumpstr[] = "received %u badtype %u bogus addr %u reqst in %u replies %u reqst out %u\n";
- static const char dumpheader[] = "IP addr Type Time Q Address Interface\n";
-
- #endif /* CATALOG */
-
-
- static const char publishstr[] = "publish";
- static const char addstr[] = "add";
- static const char netromstr[] = "netrom";
- static const char strCR[] = "%s\n";
- static const char maxqueue[] = "Max queue";
- static const char unknownstr[] = "[unknown] ";
- static const char publishedstr[] = "(published)";
-
-
- static struct cmds Arpcmds[] =
- {
- { "add", doarpadd, 0, 4, "arp add <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>"},
- { "drop", doarpdrop, 0, 3, "arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>"},
- { "dupcall", doarpdupcall, 0, 0, NULLCHAR},
- { "eaves", doarpeaves, 0, 0, NULLCHAR},
- { "expire", doarpexpire, 0, 0, NULLCHAR},
- { "flush", doarpflush, 0, 0, NULLCHAR},
- { "maxq", doarpqueue, 0, 0, NULLCHAR},
- { "poll", doarppoll, 0, 0, NULLCHAR},
- { "publish", doarpadd, 0, 4, "arp publish <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>"},
- { "sort", doarpsort, 0, 0, NULLCHAR},
- { NULLCHAR, NULL, 0, 0, NULLCHAR}
- };
-
-
- const char *Arptypes[] =
- {
- "NET/ROM",
- "10 Mb Ethernet",
- "3 Mb Ethernet",
- "AX.25",
- "Pronet",
- "Chaos",
- "",
- "Arcnet",
- "Appletalk"
- };
-
-
-
-
- int
- doarp (argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- if (argc < 2) {
- dumparp ();
- return 0;
- }
- return subcmd (Arpcmds, argc, argv, p);
- }
-
-
- static int
- doarpadd (argc, argvv, p)
- int argc;
- char *argvv[];
- void *p OPTIONAL;
- {
- char const **argv = (char const **) argvv;
- int16 hardware;
- uint32 addr;
- char *hwaddr;
- struct arp_tab *ap;
- struct arp_type *at;
- int pub = 0;
- struct iface *iface;
-
- if (argv[0][0] == 'p') /* Is this entry published? */
- pub = 1;
- if ((addr = resolve (argv[1])) == 0) {
- tprintf (Badhost, argv[1]);
- return 1;
- }
- if (argc == 4 && tolower (argv[2][0]) != 'n') {
- tprintf (addusage, pub ? publishstr : addstr);
- return -1;
- }
- /* This is a kludge. It really ought to be table driven */
- switch (tolower (argv[2][0])) {
- case 'n': /* Net/Rom pseudo-type */
- argc = 5;
- argv[4] = netromstr; /* Force use of netrom interface */
- hardware = ARP_NETROM;
- break;
- case 'e': /* "ether" */
- hardware = ARP_ETHER;
- break;
- case 'a': /* "ax25" */
- switch (tolower (argv[2][1])) {
- case 'x':
- hardware = ARP_AX25;
- break;
- case 'r':
- hardware = ARP_ARCNET;
- break;
- default:
- tprintf (addusage, pub ? publishstr : addstr);
- return -1;
- }
- break;
- case 'm': /* "mac appletalk" */
- hardware = ARP_APPLETALK;
- break;
- default:
- tprintf (addusage, pub ? publishstr : addstr);
- return -1;
- }
- if ((iface = if_lookup (argv[4])) == NULLIF) {
- tprintf (noiface, argv[4]);
- return 1;
- }
- /* If an entry already exists, clear it */
- if ((ap = arp_lookup (hardware, addr, iface)) != NULLARP)
- arp_drop (ap);
-
- at = &Arp_type[hardware];
- if (at->scan == NULLFP ((char *, const char *))) {
- tputs ("Attach device first\n");
- return 1;
- }
- /* Allocate buffer for hardware address and fill with remaining args */
- hwaddr = mallocw ((unsigned) at->hwalen);
- /* Destination address */
- (void) (*at->scan) (hwaddr, argv[3]);
- ap = arp_add (addr, hardware, hwaddr, pub, iface); /* Put in table */
- free (hwaddr); /* Clean up */
- stop_timer (&ap->timer);/* Make entry permanent */
- set_timer (&ap->timer, 0L);
- #ifdef RSPF
- rspfarpupcall (addr, hardware, NULLIF); /* Do a RSPF upcall */
- #endif /* RSPF */
- return 0;
- }
-
-
- static int
- doarpeaves (argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- return dosetflag (argc, argv, p, ARP_EAVESDROP, 0);
- }
-
-
- static int
- doarppoll (argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- return dosetflag (argc, argv, p, ARP_KEEPALIVE, 0);
- }
-
-
- static int
- doarpdupcall (argc, argv, p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- char tmp[AXBUF];
-
- if (argc < 2) {
- tprintf (strCR, pax25 (tmp, ArpDupcall));
- return 0;
- }
- if (argv[1][0]) {
- if (setcall (ArpDupcall, argv[1]) == -1)
- return -1;
- } else
- *ArpDupcall = 0;
- return 0;
- }
-
-
- static int
- doarpqueue (argc, argv, p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- return setint (&Maxarpq, maxqueue, argc, argv);
- }
-
-
- static int
- doarpexpire (argc, argv, p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- return setint (&ArpExpire, exptime, argc, argv);
- }
-
-
- /* Remove an ARP entry */
- static int
- doarpdrop (argc, argvv, p)
- int argc;
- char *argvv[];
- void *p OPTIONAL;
- {
- char const **argv = (char const **) argvv;
- int16 hardware;
- uint32 addr;
- struct arp_tab *ap;
- struct iface *iface;
-
- if ((addr = resolve (argv[1])) == 0) {
- tprintf (Badhost, argv[1]);
- return 1;
- }
- if (argc == 3 && tolower (argv[2][0]) != 'n') {
- tputs (dropusage);
- return -1;
- }
- /* This is a kludge. It really ought to be table driven */
- switch (tolower (argv[2][0])) {
- case 'n':
- argc = 4;
- argv[3] = netromstr; /* Force use of netrom interface */
- hardware = ARP_NETROM;
- break;
- case 'e': /* "ether" */
- hardware = ARP_ETHER;
- break;
- case 'a': /* "ax25" */
- switch (tolower (argv[2][1])) {
- case 'x':
- hardware = ARP_AX25;
- break;
- case 'r':
- hardware = ARP_ARCNET;
- break;
- default:
- tputs (dropusage);
- return -1;
- }
- break;
- case 'm': /* "mac appletalk" */
- hardware = ARP_APPLETALK;
- break;
- default:
- tputs (dropusage);
- return -1;
- }
- if ((iface = if_lookup (argv[3])) == NULLIF) {
- tprintf (noiface, argv[3]);
- return 1;
- }
- if ((ap = arp_lookup (hardware, addr, iface)) == NULLARP)
- return -1;
- arp_drop (ap);
- return 0;
- }
-
-
- /* Flush all automatic entries in the arp cache */
- static int
- doarpflush (argc, argv, p)
- int argc OPTIONAL;
- char *argv[] OPTIONAL;
- void *p OPTIONAL;
- {
- register struct arp_tab *ap;
- struct arp_tab *aptmp;
- int i;
-
- for (i = 0; i < HASHMOD; i++) {
- for (ap = Arp_tab[i]; ap != NULLARP; ap = aptmp) {
- aptmp = ap->next;
- if (dur_timer (&ap->timer) != 0)
- arp_drop (ap);
- }
- }
- return 0;
- }
-
-
- /* Dump ARP table */
- static void
- dumparp ()
- {
- register int i, j, k, flow_tmp;
- register struct arp_tab *ap;
- char *temp;
-
- flow_tmp = Current->flowmode;
- Current->flowmode = 1;
-
- tprintf (dumpstr, Arp_stat.recv, Arp_stat.badtype, Arp_stat.badaddr, Arp_stat.inreq,
- Arp_stat.replies, Arp_stat.outreq);
-
- for (i = 0, j = 0; i < HASHMOD; i++)
- for (ap = Arp_tab[i]; ap != (struct arp_tab *) NULL; ap = ap->next, j++) ;
-
- if (j) {
-
- tputs (dumpheader);
-
- temp = mallocw ((unsigned) j * 80);
-
- for (i = 0, k = 0; i < HASHMOD; i++) {
- for (ap = Arp_tab[i]; ap != (struct arp_tab *) NULL; ap = ap->next, k += 80)
- make_arp_string (ap, &temp[k]);
- }
-
- if (Arp_Sort)
- qsort (temp, (size_t) j, 80, (int (*)(const void *, const void *)) strcmp);
-
- for (i = 0, k = 4; i < j; i++, k += 80) {
- tputs (&temp[k]);
- if (tputc ('\n') == EOF)
- break;
- }
- free (temp);
- }
- Current->flowmode = flow_tmp;
- }
-
-
- void
- make_arp_string (ap, buf)
- register struct arp_tab *ap;
- char *buf;
- {
- char e[128];
- int a = 0;
- char *name;
-
- if (DTranslate && (name = resolve_a (ap->ip_addr, !DVerbose)) != NULLCHAR) {
- strcpy (buf, name);
- a += 4;
- free (name);
- } else
- a = SPRINTF ((buf, "%4.4s", inet_ntobos (ap->ip_addr)));
-
- a += SPRINTF ((&buf[a], "%-15.15s ", inet_ntoa (ap->ip_addr)));
- a += SPRINTF ((&buf[a], "%-14.14s ", smsg (Arptypes, NHWTYPES, (unsigned) ap->hardware)));
- a += SPRINTF ((&buf[a], "%4ld ", read_timer (&ap->timer) / 1000L));
-
- if (ap->state == ARP_PENDING)
- a += SPRINTF ((&buf[a], "%1.1u ", len_q (ap->pending)));
- else
- a += SPRINTF ((&buf[a], " "));
-
- if (ap->state == ARP_VALID) {
- if (Arp_type[ap->hardware].format != NULL)
- (void) (*Arp_type[ap->hardware].format) (e, ap->hw_addr);
- else
- e[0] = '\0';
- a += SPRINTF ((&buf[a], "%-17.17s ", e));
- } else
- a += SPRINTF ((&buf[a], unknownstr));
-
- if (ap->iface)
- a += SPRINTF ((&buf[a], "%-6.6s ", ap->iface->name));
-
- if (ap->pub)
- a += SPRINTF ((&buf[a], publishedstr));
-
- return;
- }
-
-
- /* Sort ARP dump */
- static int
- doarpsort (argc, argv, p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- return setbool (&Arp_Sort, "ARP Sort flag", argc, argv);
- }
-